---
title: "模組系統與建置工具"
description: "學習 Rust 的模組系統、套件管理和專案結構，對比 JavaScript 的模組化開發"
---

# 模組系統與建置工具

## 📖 學習目標

了解 Rust 的模組系統和套件管理工具 Cargo，學會如何組織 Rust 專案結構，並理解與 JavaScript 模組系統的差異。

---

## 🎯 模組系統對比

### JavaScript 的模組系統

JavaScript 使用 ES6 模組語法：

<UniversalEditor title="JavaScript 模組系統" compare={true}>
```javascript !! js
// math.js - 匯出模組
export const PI = 3.14159;

export function add(a, b) {
    return a + b;
}

export function multiply(a, b) {
    return a * b;
}

// 預設匯出
export default class Calculator {
    constructor() {
        this.result = 0;
    }
    
    add(x) {
        this.result += x;
        return this;
    }
    
    getResult() {
        return this.result;
    }
}

// utils.js - 另一個模組
export function formatNumber(num) {
    return num.toFixed(2);
}

// main.js - 匯入模組
import Calculator, { add, multiply, PI } from './math.js';
import { formatNumber } from './utils.js';

console.log(PI); // 3.14159
console.log(add(5, 3)); // 8
console.log(multiply(4, 2)); // 8

const calc = new Calculator();
calc.add(10).add(5);
console.log(calc.getResult()); // 15

console.log(formatNumber(3.14159)); // "3.14"
```
</UniversalEditor>

### Rust 的模組系統

Rust 使用 `mod` 和 `use` 關鍵字管理模組：

<UniversalEditor title="Rust 模組系統" compare={true}>
```rust !! rs
// lib.rs - 主模組檔案
mod math; // 宣告 math 模組
mod utils; // 宣告 utils 模組

// 重新匯出模組內容
pub use math::{add, multiply, PI, Calculator};
pub use utils::format_number;

// math.rs - 數學模組
pub const PI: f64 = 3.14159;

pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

pub fn multiply(a: i32, b: i32) -> i32 {
    a * b
}

// 結構體（類似 JavaScript 的類別）
pub struct Calculator {
    result: i32,
}

impl Calculator {
    // 建構函式
    pub fn new() -> Self {
        Calculator { result: 0 }
    }
    
    pub fn add(&mut self, x: i32) -> &mut Self {
        self.result += x;
        self
    }
    
    pub fn get_result(&self) -> i32 {
        self.result
    }
}

// utils.rs - 工具模組
pub fn format_number(num: f64) -> String {
    format!("{:.2}", num)
}

// main.rs - 主程式
// 假設 `langshift-project` 是 crate（專案）的名稱
use langshift_project::math::{add, multiply, PI, Calculator};
use langshift_project::utils::format_number;

fn main() {
    println!("PI = {}", PI); // PI = 3.14159
    println!("add(5, 3) = {}", add(5, 3)); // add(5, 3) = 8
    println!("multiply(4, 2) = {}", multiply(4, 2)); // multiply(4, 2) = 8
    
    let mut calc = Calculator::new();
    calc.add(10).add(5);
    println!("calc result = {}", calc.get_result()); // calc result = 15
    
    println!("formatted: {}", format_number(3.14159)); // formatted: 3.14
}
```
</UniversalEditor>

### 模組系統差異

1.  **檔案組織**: Rust 使用 `mod` 宣告模組，JavaScript 使用檔案路徑
2.  **可見性**: Rust 需要明確宣告 `pub` 來公開函式和結構體
3.  **匯入語法**: Rust 使用 `use` 關鍵字，JavaScript 使用 `import`
4.  **預設匯出**: Rust 沒有預設匯出的概念，需要明確匯入

---

## 📦 套件管理系統對比

### JavaScript 的 npm

<UniversalEditor title="JavaScript 套件管理" compare={true}>
```json !! json
// package.json
{
  "name": "langshift-project",
  "version": "1.0.0",
  "description": "JavaScript 到 Rust 學習專案",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "jest",
    "build": "webpack"
  },
  "dependencies": {
    "lodash": "^4.17.21",
    "express": "^4.18.2"
  },
  "devDependencies": {
    "jest": "^29.5.0",
    "webpack": "^5.88.0"
  }
}
```
```bash
# 安裝相依性
npm install lodash express
npm install --save-dev jest webpack
```
```javascript
// 使用相依性
import _ from 'lodash';
import express from 'express';

const app = express();
const numbers = [1, 2, 3, 4, 5];
const sum = _.sum(numbers);

console.log(sum); // 15
```
</UniversalEditor>

### Rust 的 Cargo

<UniversalEditor title="Rust 套件管理" compare={true}>
```toml !! toml
// Cargo.toml - 專案設定檔
[package]
name = "langshift-project"
version = "0.1.0"
edition = "2021"
authors = ["Your Name <your.email@example.com>"]
description = "JavaScript 到 Rust 學習專案"

[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }
reqwest = { version = "0.11", features = ["json"] }

[dev-dependencies]
tokio-test = "0.4"
```
```bash
# 新增相依性
cargo add serde tokio reqwest
cargo add --dev tokio-test
```
```rust
// main.rs - 使用相依性
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct User {
    name: String,
    age: u32,
}

#[tokio::main]
async fn main() {
    let user = User {
        name: String::from("Rust"),
        age: 25,
    };
    
    // 序列化為 JSON
    let json = serde_json::to_string(&user).unwrap();
    println!("JSON: {}", json);
    
    // 非同步任務
    tokio::spawn(async {
        println!("非同步任務執行中...");
    });
}
```
</UniversalEditor>

### 套件管理差異

1.  **設定檔**: npm 使用 `package.json`，Cargo 使用 `Cargo.toml`
2.  **相依性管理**: Cargo 的相依性管理更嚴格，版本衝突處理更好
3.  **建置工具**: Cargo 整合了建置、測試、文件產生等功能
4.  **特性系統**: Rust 支援條件式編譯和特性標誌 